<script>
import {
  GlAlert,
  GlBadge,
  GlLink,
  GlLoadingIcon,
  GlSprintf,
  GlTable,
  GlTooltip,
  GlTooltipDirective,
} from '@gitlab/ui';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { s__, sprintf } from '~/locale';
import CiBadgeLink from '~/vue_shared/components/ci_badge_link.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import StateActions from './states_table_actions.vue';

export default {
  components: {
    CiBadgeLink,
    GlAlert,
    GlBadge,
    GlLink,
    GlLoadingIcon,
    GlSprintf,
    GlTable,
    GlTooltip,
    StateActions,
    TimeAgoTooltip,
  },
  directives: {
    GlTooltip: GlTooltipDirective,
  },
  mixins: [timeagoMixin],
  props: {
    states: {
      required: true,
      type: Array,
    },
    terraformAdmin: {
      required: false,
      type: Boolean,
      default: false,
    },
  },
  computed: {
    fields() {
      const columns = [
        {
          key: 'name',
          label: this.$options.i18n.name,
        },
        {
          key: 'pipeline',
          label: this.$options.i18n.pipeline,
        },
        {
          key: 'updated',
          label: this.$options.i18n.details,
        },
      ];

      if (this.terraformAdmin) {
        columns.push({
          key: 'actions',
          label: this.$options.i18n.actions,
          thClass: 'gl-w-12',
          tdClass: 'gl-text-right',
        });
      }

      return columns;
    },
  },
  i18n: {
    actions: s__('Terraform|Actions'),
    details: s__('Terraform|Details'),
    jobStatus: s__('Terraform|Job status'),
    locked: s__('Terraform|Locked'),
    lockedByUser: s__('Terraform|Locked by %{user} %{timeAgo}'),
    lockingState: s__('Terraform|Locking state'),
    deleting: s__('Terraform|Removed'),
    deletionInProgress: s__('Terraform|Deletion in progress'),
    name: s__('Terraform|Name'),
    pipeline: s__('Terraform|Pipeline'),
    removing: s__('Terraform|Removing'),
    unknownUser: s__('Terraform|Unknown User'),
    unlockingState: s__('Terraform|Unlocking state'),
    updatedUser: s__('Terraform|%{user} updated %{timeAgo}'),
  },
  methods: {
    createdByUserName(item) {
      return item.latestVersion?.createdByUser?.name;
    },
    loadingLockText(item) {
      return item.lockedAt ? this.$options.i18n.unlockingState : this.$options.i18n.lockingState;
    },
    lockedByUserName(item) {
      return item.lockedByUser?.name || this.$options.i18n.unknownUser;
    },
    lockedByUserText(item) {
      return sprintf(this.$options.i18n.lockedByUser, {
        user: this.lockedByUserName(item),
        timeAgo: this.timeFormatted(item.lockedAt),
      });
    },
    pipelineDetailedStatus(item) {
      return item.latestVersion?.job?.detailedStatus;
    },
    pipelineID(item) {
      let id = item.latestVersion?.job?.pipeline?.id;

      if (id) {
        id = getIdFromGraphQLId(id);
      }

      return id;
    },
    pipelinePath(item) {
      return item.latestVersion?.job?.pipeline?.path;
    },
    updatedTime(item) {
      return item.latestVersion?.updatedAt || item.updatedAt;
    },
  },
};
</script>

<template>
  <gl-table
    :items="states"
    :fields="fields"
    data-testid="terraform-states-table"
    details-td-class="gl-p-0!"
    fixed
    stacked="md"
  >
    <template #cell(name)="{ item }">
      <div
        class="gl-display-flex align-items-center gl-justify-content-end gl-md-justify-content-start"
        data-testid="terraform-states-table-name"
      >
        <p class="gl-font-weight-bold gl-m-0 gl-text-gray-900">
          {{ item.name }}
        </p>

        <div v-if="item.loadingLock" class="gl-mx-3">
          <p class="gl-display-flex gl-justify-content-start gl-align-items-baseline gl-m-0">
            <gl-loading-icon size="sm" class="gl-pr-1" />
            {{ loadingLockText(item) }}
          </p>
        </div>

        <div v-else-if="item.loadingRemove" class="gl-mx-3">
          <p
            class="gl-display-flex gl-justify-content-start gl-align-items-baseline gl-m-0 gl-text-red-500"
          >
            <gl-loading-icon size="sm" class="gl-pr-1" />
            {{ $options.i18n.removing }}
          </p>
        </div>

        <div
          v-else-if="item.deletedAt"
          v-gl-tooltip.right
          class="gl-mx-3"
          :title="$options.i18n.deletionInProgress"
          :data-testid="`state-badge-${item.name}`"
        >
          <gl-badge icon="remove">
            {{ $options.i18n.deleting }}
          </gl-badge>
        </div>

        <div
          v-else-if="item.lockedAt"
          v-gl-tooltip.right
          class="gl-mx-3"
          :title="lockedByUserText(item)"
          :data-testid="`state-badge-${item.name}`"
        >
          <gl-badge icon="lock">
            {{ $options.i18n.locked }}
          </gl-badge>
        </div>
      </div>
    </template>

    <template #cell(pipeline)="{ item }">
      <div data-testid="terraform-states-table-pipeline" class="gl-min-h-7">
        <gl-link v-if="pipelineID(item)" :href="pipelinePath(item)">
          #{{ pipelineID(item) }}
        </gl-link>

        <div
          v-if="pipelineDetailedStatus(item)"
          :id="`terraformJobStatusContainer${item.name}`"
          class="gl-my-2"
        >
          <ci-badge-link
            :id="`terraformJobStatus${item.name}`"
            :status="pipelineDetailedStatus(item)"
            class="gl-py-1"
          />

          <gl-tooltip
            :container="`terraformJobStatusContainer${item.name}`"
            :target="`terraformJobStatus${item.name}`"
            placement="right"
          >
            {{ $options.i18n.jobStatus }}
          </gl-tooltip>
        </div>
      </div>
    </template>

    <template #cell(updated)="{ item }">
      <p class="gl-m-0" data-testid="terraform-states-table-updated">
        <gl-sprintf :message="$options.i18n.updatedUser">
          <template #user>
            <span v-if="item.latestVersion">
              {{ createdByUserName(item) }}
            </span>
          </template>

          <template #timeAgo>
            <time-ago-tooltip :time="updatedTime(item)" />
          </template>
        </gl-sprintf>
      </p>
    </template>

    <template v-if="terraformAdmin" #cell(actions)="{ item }">
      <state-actions :state="item" />
    </template>

    <template #row-details="row">
      <gl-alert
        data-testid="terraform-states-table-error"
        variant="danger"
        @dismiss="row.toggleDetails"
      >
        <span
          v-for="errorMessage in row.item.errorMessages"
          :key="errorMessage"
          class="gl-display-flex gl-justify-content-start"
        >
          {{ errorMessage }}
        </span>
      </gl-alert>
    </template>
  </gl-table>
</template>
